import cv2
import numpy as np
import os
import logging
import time
from language_config import LANGUAGES, DEFAULT_LANGUAGE

class RemoteUIController:
    def __init__(self, width=480, height=800, fullscreen=True, theme_name="gray_theme", language=DEFAULT_LANGUAGE, debug_mode=False):
        self.debug_mode = debug_mode
        self.W = width
        self.H = height
        self.fullscreen = fullscreen
        self.canvas = np.zeros((height, width, 3), dtype=np.uint8)
        self.buttons = {}
        self.running = True
        self.status_history = []
        self.max_history_lines = 4
        self.last_mouse_pos = (0, 0)
        self.mouse_click = False
        self.window_created = False
        self.theme_name = theme_name
        self.language = language
        self.texts = LANGUAGES.get(self.language, LANGUAGES[DEFAULT_LANGUAGE])
        self.colors = self._load_theme_colors()
        
        # 颜色配置（动态从 theme_config.py 获取）
        self.colors = self._load_theme_colors()
        
        # 字体配置
        self.fonts = {}
        self._load_fonts()
        
        # 设置日志
        self.logger = logging.getLogger("RemoteController")
    
    def _load_theme_colors(self):
        """从 theme_config.py 加载主题颜色"""
        try:
            from theme_config import THEMES
            theme = THEMES.get(self.theme_name, THEMES["gray_theme"])
            
            # 转换十六进制颜色为 BGR 格式
            def hex_to_bgr(hex_color):
                hex_color = hex_color.lstrip('#')
                if len(hex_color) == 3:
                    hex_color = ''.join([c * 2 for c in hex_color])
                return tuple(int(hex_color[i:i+2], 16) for i in (4, 2, 0))
            
            return {
                'background': hex_to_bgr(theme["background"]),
                'text': hex_to_bgr(theme["text"]),
                'cmd_text': (150, 255, 150),
                'error_text': (255, 150, 150),
                'info_text': (150, 200, 255),
                'button_primary': hex_to_bgr(theme["button"]),
                'button_success': (100, 220, 100),
                'button_warning': (220, 180, 100),
                'button_danger': (220, 100, 100),
                'button_secondary': hex_to_bgr(theme["button_hover"]),
            }
        except Exception as e:
            self.logger.error(f"{self.texts['theme_load_failed']}: {e}")
            # 返回默认颜色
            return {
                'background': (100, 100, 100),
                'text': (240, 240, 240),
                'cmd_text': (150, 255, 150),
                'error_text': (255, 150, 150),
                'info_text': (150, 200, 255),
                'button_primary': (220, 220, 220),
                'button_success': (100, 220, 100),
                'button_warning': (220, 180, 100),
                'button_danger': (220, 100, 100),
                'button_secondary': (150, 150, 180),
            }
    
    def _load_fonts(self):
        """加载字体（使用OpenCV内置字体）"""
        self.fonts = {
            20: cv2.FONT_HERSHEY_SIMPLEX,
            24: cv2.FONT_HERSHEY_SIMPLEX,
            28: cv2.FONT_HERSHEY_SIMPLEX,
            32: cv2.FONT_HERSHEY_SIMPLEX,
            36: cv2.FONT_HERSHEY_SIMPLEX
        }
    
    def create_window(self):
        """创建窗口"""
        try:
            if self.fullscreen:
                # 全屏模式，隐藏窗口标题栏
                cv2.namedWindow("Remote", cv2.WINDOW_NORMAL)
                cv2.setWindowProperty("Remote", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
                # 在全屏模式下隐藏鼠标光标
                cv2.setMouseCallback("Remote", self._mouse_callback)
            else:
                cv2.namedWindow("Remote", cv2.WINDOW_NORMAL)
                cv2.resizeWindow("Remote", self.W, self.H)
                cv2.setMouseCallback("Remote", self._mouse_callback)
            
            self.window_created = True
            self.logger.info(self.texts["window_created"])
            return True
        except Exception as e:
            self.logger.error(f"{self.texts['window_failed']}: {e}")
            return False
    
    def add_button(self, name, x, y, width, height, color_type='primary', callback=None):
        """添加按钮（修复文本字段缺失问题）"""
        color_map = {
            'primary': self.colors['button_primary'],
            'success': self.colors['button_success'],
            'warning': self.colors['button_warning'],
            'danger': self.colors['button_danger'],
            'secondary': self.colors['button_secondary'],
        }
        
        self.buttons[name] = {
            'xy': (x, y),
            'wh': (width, height),
            'color': color_map.get(color_type, self.colors['button_primary']),
            'callback': callback,
            'text': name  # 确保按钮信息中包含文本字段
        }
    
    def _put_text(self, img, text, pos, size=32, color=(255, 255, 255), align="left"):
        """绘制文本（支持中文）"""
        try:
            x, y = pos
            font_scale = size / 40
            thickness = 2
            
            # 尝试加载中文字体（如果存在）
            font_path = "/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc"  # 文泉驿正黑字体
            if os.path.exists(font_path):
                from PIL import Image, ImageDraw, ImageFont
                import numpy as np
                
                # 使用PIL绘制中文
                img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
                draw = ImageDraw.Draw(img_pil)
                font = ImageFont.truetype(font_path, size)
                
                # 计算文本尺寸和对齐
                text_width, text_height = draw.textsize(text, font=font)
                if align == "center":
                    x -= text_width // 2
                elif align == "right":
                    x -= text_width
                
                # 垂直居中调整（PIL）
                y -= text_height // 2  # 调整为向上移动更多
                
                # 绘制文本
                draw.text((x, y), text, font=font, fill=color)
                img = cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
            else:
                # 回退到OpenCV默认字体（仅支持英文）
                (text_width, text_height), _ = cv2.getTextSize(text, cv2.FONT_HERSHEY_SIMPLEX, font_scale, thickness)
                if align == "center":
                    x -= text_width // 2
                elif align == "right":
                    x -= text_width
                # 垂直居中调整（OpenCV）
                y += text_height // 3  # 调整为向上移动更多
                cv2.putText(img, text, (x, y), cv2.FONT_HERSHEY_SIMPLEX, font_scale, color, thickness)
            
            return img
        except Exception as e:
            self.logger.error(f"绘制文本失败: {e}")
            return img
    
    def _draw_rounded_rect(self, img, center, size, color, corner_radius=20):
        """绘制圆角矩形"""
        cx, cy = center
        w, h = size
        
        x1, y1 = cx - w // 2, cy - h // 2
        x2, y2 = cx + w // 2, cy + h // 2
        
        # 绘制阴影
        shadow_color = (max(0, color[0]//3), max(0, color[1]//3), max(0, color[2]//3))
        self._draw_rounded_rect_segment(img, (cx, cy+4), (w, h), shadow_color, corner_radius)
        
        # 绘制主按钮
        self._draw_rounded_rect_segment(img, center, (w, h), color, corner_radius)
        
        return (x1, y1, x2, y2)
    
    def _draw_button(self, button_name):
        """绘制单个按钮（修复颜色和文本显示问题）"""
        if button_name not in self.buttons:
            return
            
        info = self.buttons[button_name]
        center = info['xy']
        size = info['wh']
        color = info['color']
        
        # 绘制按钮背景
        self._draw_rounded_rect(self.canvas, center, size, color, corner_radius=20)
        
        # 绘制按钮文本（确保文本颜色与背景对比明显）
        text_color = (30, 30, 30) if sum(color) >= 400 else (240, 240, 240)
        # 强制文本颜色为黑色或白色，确保对比度
        if sum(color) >= 400:
            text_color = (0, 0, 0)  # 黑色
        else:
            text_color = (255, 255, 255)  # 白色
        self._put_text(self.canvas, info['text'], center, size=32, color=text_color, align="center")
        
        # 强制刷新显示
        if self.window_created:
            cv2.imshow("Remote", self.canvas)
            cv2.waitKey(1)
        
        # 确保画布更新（修复文本消失问题）
        self.canvas = np.copy(self.canvas)
    
    def _draw_rounded_rect_segment(self, img, center, size, color, corner_radius):
        """绘制圆角矩形的各个部分"""
        cx, cy = center
        w, h = size
        
        x1, y1 = cx - w // 2, cy - h // 2
        x2, y2 = cx + w // 2, cy + h // 2
        
        # 绘制矩形主体
        cv2.rectangle(img, (x1 + corner_radius, y1), (x2 - corner_radius, y2), color, -1)
        cv2.rectangle(img, (x1, y1 + corner_radius), (x2, y2 - corner_radius), color, -1)
        
        # 绘制四个圆角
        cv2.ellipse(img, (x1 + corner_radius, y1 + corner_radius), (corner_radius, corner_radius), 0, 180, 270, color, -1)
        cv2.ellipse(img, (x2 - corner_radius, y1 + corner_radius), (corner_radius, corner_radius), 0, 270, 360, color, -1)
        cv2.ellipse(img, (x1 + corner_radius, y2 - corner_radius), (corner_radius, corner_radius), 0, 90, 180, color, -1)
        cv2.ellipse(img, (x2 - corner_radius, y2 - corner_radius), (corner_radius, corner_radius), 0, 0, 90, color, -1)
    
    def draw_interface(self, force_full_redraw=False):
        """绘制界面（支持部分刷新）"""
        try:
            if force_full_redraw or not hasattr(self, '_last_canvas'):
                # 首次或强制重绘整个界面
                self.canvas[:] = self.colors['background']
                title = "Remote Controller"
                self.canvas = self._put_text(self.canvas, title, (self.W // 2, 40), 
                                            size=36, color=self.colors['text'], align="center")
                
                for name, info in self.buttons.items():
                    center = info['xy']
                    size = info['wh']
                    color = info['color']
                    
                    x1, y1, x2, y2 = self._draw_rounded_rect(self.canvas, center, size, color, corner_radius=20)
                    
                    text_color = (30, 30, 30) if sum(color) >= 400 else (240, 240, 240)
                    self.canvas = self._put_text(self.canvas, name, center, 
                                                size=32, color=text_color, align="center")
                
                self._draw_status_area()
                self._last_canvas = self.canvas.copy()
            else:
                # 仅更新状态区域
                self._draw_status_area()
                
            return self.canvas
        except Exception as e:
            self.logger.error(f"绘制界面失败: {e}")
            error_canvas = np.zeros((self.H, self.W, 3), dtype=np.uint8)
            cv2.putText(error_canvas, "UI Error", (self.W//2-50, self.H//2), 
                       cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2)
            return error_canvas
    
    def _draw_status_area(self):
        """绘制状态显示区域 - 优化布局"""
        try:
            # 状态区域背景 - 调整位置和大小
            status_x1, status_y1 = 20, 610  # 向上移动，避免遮挡
            status_x2, status_y2 = self.W-20, 780
            cv2.rectangle(self.canvas, (status_x1, status_y1), (status_x2, status_y2), 
                         self.colors['background'], -1)
            cv2.rectangle(self.canvas, (status_x1, status_y1), (status_x2, status_y2), 
                         self.colors['button_secondary'], 2)
            
            # 状态区域标题 - 居中显示
            status_title_x = (status_x1 + status_x2) // 2
            status_title_y = status_y1 + 25  # 向下调整，给标题更多空间
            self.canvas = self._put_text(self.canvas, "Status", (status_title_x, status_title_y), 
                                        size=24, color=self.colors['text'], align="center")
            
            # 绘制分隔线 - 在标题下方
            separator_y = status_title_y + 20
            cv2.line(self.canvas, (status_x1 + 10, separator_y), 
                    (status_x2 - 10, separator_y), (80, 80, 120), 1)
            
            # 显示状态历史 - 左对齐，并确保在边框内
            status_padding = 15  # 内边距
            text_start_x = status_x1 + status_padding
            text_start_y = separator_y + 20  # 从分隔线下方开始
            
            # 清空状态区域内的内容（除了边框）
            cv2.rectangle(self.canvas, 
                         (status_x1 + 2, separator_y + 2), 
                         (status_x2 - 2, status_y2 - 2), 
                         (40, 40, 60), -1)
            
            # 显示状态历史，确保在边框内
            for i, status in enumerate(self.status_history[-self.max_history_lines:]):
                color = self.colors['info_text']
                if "error" in status.lower() or "fail" in status.lower():
                    color = self.colors['error_text']
                elif "success" in status.lower() or "done" in status.lower():
                    color = self.colors['cmd_text']
                    
                # 确保文本不会超出状态区域
                text_y = text_start_y + i * 25
                if text_y < status_y2 - 10:  # 确保有足够空间
                    self.canvas = self._put_text(self.canvas, status, 
                                                (text_start_x, text_y), 
                                                size=20, color=color, align="left")
        except Exception as e:
            self.logger.error(f"绘制状态区域失败: {e}")
    
    def update_status(self, status_text):
        """高效更新状态显示"""
        try:
            self.status_history.append(status_text)
            if len(self.status_history) > 10:
                self.status_history = self.status_history[-10:]
            
            # 仅重绘状态区域
            self._draw_status_area()
            
            # 直接更新窗口显示（跳过完整重绘）
            if self.window_created:
                cv2.imshow("Remote", self.canvas)
                cv2.waitKey(1)  # 强制刷新显示
            
            return self.canvas
        except Exception as e:
            self.logger.error(f"更新状态失败: {e}")
            return self.canvas
    
    def log_message(self, message, msg_type="info"):
        """记录消息到状态区域"""
        try:
            type_prefix = {
                "info": "[INFO]",
                "error": "[ERROR]",
                "success": "[SUCCESS]",
                "warning": "[WARNING]"
            }.get(msg_type, "[INFO]")
            
            full_message = f"{type_prefix} {message}"
            self.update_status(full_message)
            
            # 同时记录到日志文件
            if msg_type == "error":
                self.logger.error(message)
            elif msg_type == "warning":
                self.logger.warning(message)
            else:
                self.logger.info(message)
        except Exception as e:
            self.logger.error(f"记录消息失败: {e}")
    
    def _mouse_callback(self, event, x, y, flags, param):
        """鼠标事件回调"""
        if event == cv2.EVENT_LBUTTONDOWN:
            try:
                for name, info in self.buttons.items():
                    cx, cy = info['xy']
                    w, h = info['wh']
                    
                    if (cx - w // 2 <= x <= cx + w // 2 and 
                        cy - h // 2 <= y <= cy + h // 2):
                        
                        if info['callback']:
                            info['callback'](name)
                        
                        self._button_click_feedback(name)
                        break
            except Exception as e:
                self.logger.error(f"处理鼠标点击失败: {e}")
    
    def _button_click_feedback(self, button_name):
        """线程安全的按钮点击反馈（修复文字不显示问题）"""
        if button_name not in self.buttons:
            return
            
        info = self.buttons[button_name]
        original_color = info['color']
        
        # 高亮按钮
        info['color'] = tuple(min(c + 50, 255) for c in original_color)
        # 强制绘制按钮文本（避免被覆盖）
        self._put_text(self.canvas, info['text'], info['xy'], size=32, 
                      color=(0, 0, 0) if sum(info['color']) >= 400 else (255, 255, 255), 
                      align="center")
        
        # 强制刷新显示
        if self.window_created:
            cv2.imshow("Remote", self.canvas)
            cv2.waitKey(1)
        
        # 非阻塞延迟（使用事件循环代替sleep）
        start_time = time.time()
        while time.time() - start_time < 0.1:  # 100ms反馈时间
            if self.window_created:
                cv2.waitKey(10)
        
        # 恢复按钮颜色
        info['color'] = original_color
        # 强制重新绘制按钮文本
        self._put_text(self.canvas, info['text'], info['xy'], size=32, 
                      color=(0, 0, 0) if sum(original_color) >= 400 else (255, 255, 255), 
                      align="center")
        
        # 强制刷新显示
        if self.window_created:
            cv2.imshow("Remote", self.canvas)
            cv2.waitKey(1)
        
        # 确保画布更新（修复文本消失问题）
        self.canvas = np.copy(self.canvas)
    
    def get_canvas(self):
        """获取画布"""
        return self.canvas
    
    def is_running(self):
        """检查程序是否在运行"""
        if not self.window_created:
            return True
            
        try:
            if cv2.getWindowProperty("Remote", cv2.WND_PROP_VISIBLE) < 1:
                self.running = False
            return self.running
        except:
            # 如果检查窗口属性失败，假设窗口已关闭
            self.running = False
            return False
    
    def wait_key(self, delay=20):
        """等待按键"""
        if not self.window_created:
            return 255
            
        try:
            key = cv2.waitKey(delay) & 0xFF
            if key == ord('q') or key == 27:  # 'q' 或 ESC
                self.running = False
            return key
        except Exception as e:
            self.logger.error(f"等待按键失败: {e}")
            return 255
    
    def set_theme(self, theme_name):
        """动态切换主题"""
        try:
            self.theme_name = theme_name
            self.colors = self._load_theme_colors()
            self.draw_interface()
            self.logger.info(f"主题已切换为: {theme_name}")
            return True
        except Exception as e:
            self.logger.error(f"切换主题失败: {e}")
            return False
            
    def set_language(self, language):
        """动态切换语言"""
        try:
            if language in LANGUAGES:
                self.language = language
                self.texts = LANGUAGES[language]
                self.draw_interface()
                self.logger.info(f"语言已切换为: {language}")
                return True
            else:
                self.logger.error(f"不支持的语言: {language}")
                return False
        except Exception as e:
            self.logger.error(f"切换语言失败: {e}")
            return False
    
    def close(self):
        """关闭界面"""
        try:
            # 标记程序停止
            self.running = False
            
            # 关闭所有OpenCV窗口
            if self.window_created:
                cv2.destroyAllWindows()
            
            # 清理按钮回调（避免残留线程）
            for name, info in self.buttons.items():
                info['callback'] = None
            
            # 关闭Go2控制器
            if hasattr(self, 'go2_controller') and self.go2_controller:
                self.go2_controller.close()
            
            self.logger.info("界面已关闭")
        except Exception as e:
            self.logger.error(f"关闭界面失败: {e}")